package com.michael.xx.audiorecoder;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaPlayer;
import android.os.Handler;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.michael.xx.audiorecoder.encoder.Mp3Encoder;
import com.michael.xx.audiorecoder.encoder.WavEncoder;
import com.michael.xx.audiorecoder.utils.FormatUtils;

import java.io.IOException;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView tvRecord;
    private TextView tvPlay;

    private AudioRecorder audioRecorder;
    private MediaPlayer mediaPlayer;
    private Handler handler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.btn_player).setOnClickListener(this);
        findViewById(R.id.btn_recorder).setOnClickListener(this);
        findViewById(R.id.btn_recorder_paused).setOnClickListener(this);
        findViewById(R.id.btn_reinit).setOnClickListener(this);
        findViewById(R.id.btn_recorder_stop).setOnClickListener(this);
        findViewById(R.id.btn_recorder_resume).setOnClickListener(this);


        tvRecord = (TextView) findViewById(R.id.tv_recorder_timer);
        tvPlay = (TextView) findViewById(R.id.tv_player_timer);

        queryNativeAudioParameters();
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED ||
                ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ||
                ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
        ) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO}, 1);
        } else {
            initRecorder();
        }
        initPlayer();
        MediaExtractor mex = new MediaExtractor();
        try {
            mex.setDataSource("/sdcard/audiorecord/mp3/single_channel.mp3");
        } catch (IOException e ) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        MediaFormat mf = mex.getTrackFormat(0);
        int bitRate = mf.getInteger(MediaFormat.KEY_BIT_RATE);//比特率
        int sampleRate = mf.getInteger(MediaFormat.KEY_SAMPLE_RATE);//采样率
        int channelCount = mf.getInteger(MediaFormat.KEY_CHANNEL_COUNT);//通道数
        int digit = bitRate*8/(sampleRate*channelCount);//采样位
        Log.d("TAG", "getSampleRate: bitRate:"+bitRate);
        Log.d("TAG", "getSampleRate: sampleRate:"+sampleRate);
        Log.d("TAG", "getSampleRate: channelCount:"+channelCount);
        Log.d("TAG", "getSampleRate: digit:"+digit);


    }

    private void initPlayer() {
        mediaPlayer = new MediaPlayer();
        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                mediaPlayer.start();
            }
        });
    }

    public Runnable updateTimeTask = new Runnable() {
        @Override
        public void run() {
            if (mediaPlayer != null) {
                int currentPosition = mediaPlayer.getCurrentPosition();
                tvRecord.setText(FormatUtils.format(currentPosition / 1000));
                handler.postDelayed(updateTimeTask, 1000);
            }
        }
    };

    private void initRecorder() {
        audioRecorder = new AudioRecorder(new AudioRecorder.CallBack() {
            @Override
            public void onTimeUpdate(final int progress) {
                tvRecord.post(new Runnable() {
                    @Override
                    public void run() {
                        tvRecord.setText(FormatUtils.format(progress));
                    }
                });
            }
        }, new Mp3Encoder());
        audioRecorder.setSampleRateInHz(mSampleRateInHz);
        audioRecorder.setAudioInput(1);
    }
    boolean supportRecording;
    String nativeSampleRate;
    String nativeSampleBufSize;
    private int mSampleRateInHz;
    private int mRecBufSize;
    private void queryNativeAudioParameters() {
        supportRecording = true;
        AudioManager myAudioMgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        if (myAudioMgr == null) {
            supportRecording = false;
            return;
        }
        nativeSampleRate = myAudioMgr.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
        nativeSampleBufSize = myAudioMgr.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER);

        // hardcoded channel to mono: both sides -- C++ and Java sides
        mSampleRateInHz = Integer.parseInt(nativeSampleRate);
        mRecBufSize = AudioRecord.getMinBufferSize(
                mSampleRateInHz,
                AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_PCM_16BIT);
        if (mRecBufSize == AudioRecord.ERROR ||
                mRecBufSize == AudioRecord.ERROR_BAD_VALUE) {
            supportRecording = false;
        }
        if (!supportRecording) {
            Toast.makeText(this, "设备不支持录音", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED ||
                ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ||
                ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
        ) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO}, 1);
        } else {
            initRecorder();
        }
    }

    @Override
    public void onClick(View v) {
        handler.removeCallbacks(updateTimeTask);
        switch (v.getId()) {
            case R.id.btn_player:
                try {
                    mediaPlayer.reset();
                    mediaPlayer.setDataSource(audioRecorder.getVoiceFilePath());
//                    mediaPlayer.setDataSource(AudioFileUtils.getMP3FileAbsolutePath("single_channel"));
                    mediaPlayer.prepareAsync();
                    handler.removeCallbacks(updateTimeTask);
                    handler.post(updateTimeTask);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
            case R.id.btn_recorder:
                audioRecorder.startRecord();
                break;
            case R.id.btn_recorder_paused:
                audioRecorder.pause();
                break;
            case R.id.btn_reinit:
                initRecorder();
                break;
            case R.id.btn_recorder_stop:
                audioRecorder.stop();
                tvRecord.setText(FormatUtils.format(0 / 1000));
                break;
            case R.id.btn_recorder_resume:
                if (audioRecorder.isInited()) {
                    audioRecorder.resume();
                }
                break;
        }
    }
}
